<?php
/**
 * 支持分库分表操作的 AR 基类
 */
class CShardedActiveRecord extends CActiveRecord {
	/**
	 * 当前使用的数据库连接
	 * @var Object
	 */
	private static $_dbConnection = null;
	
	/**
	 * 分表名
	 * 基础表名.'_'.分表键值
	 */
	private static $_shardedTable = '';
	
	/**
	 * 分库值
	 */
	private static $_shardedValue = '';
	
	/**
	 * 基础表名
	 */
	protected static $baseTable = '';
	
	public static function model($className = __CLASS__) {
		self::choose();
		
		$model = parent::model($className);
		
		$model->refreshMetaData();
		return $model;
	}

	/**
	 * 获取数据库连接
	 */
	public function getDbConnection() {
		if(empty(self::$_dbConnection)) {
			return parent::getDbConnection();
		}
		
		return self::$_dbConnection;
	}
	
	/**
	 * 根据 $_shardedValue 选择对应的数据库 和 数据表
	 */
	private static function choose() {
		if(null === self::$_shardedValue) throw new CDbException('Sharded value is not set! Please call self::setShardedValue($value) first.');
		
		CDbManager::conn()->sharded(self::$_shardedValue);
		
		self::chooseDb();
		self::chooseTable();
	}
	
	/**
	 * 选择数据库，并建立相应连接
	 */
	private static function chooseDb() {
		self::$_dbConnection = CDbManager::conn()->getDbConnection();
		
		if(!self::$_dbConnection) throw new CDbException('Connections not found!');
	}
	
	/**
	 * 选择表
	 */
	private static function chooseTable() {
		if(empty(static::$baseTable)) throw new Exception('You must set the table name first! In your model.');
		$key = CDbManager::conn()->shardedTableKey;
		
		self::$_shardedTable = sprintf("%s_%s", static::$baseTable, $key);
	}
	
	/**
	 * 获取表名
	 */
	public function tableName() {
		return self::$_shardedTable;
	}
	
	/**
	 * 获取分库分表值
	 */
	public static function getShardedValue() {
		return self::$_shardedValue;
	}
	
	/**
	 * 设置分库分表值
	 * @param $value
	 */
	public static function setShardedValue($value) {
		null !== $value && self::$_shardedValue = $value;
	}
}